/*                          UX-Framework                               
 *                                                                 
 *  iZE Co.,Ltd. Copyright 2009 All rights reserved.          
 *  This file is distributed under the terms of the GNU Lesser 
 *  General Public License, described in file LICENSE.                                     
 */
package jp.ize.ux.components;

// {{{ imports
import jp.ize.ux.UXObject;
import jp.ize.ux.UXController;
import jp.ize.ux.UXInteraction;
import jp.ize.ux.UXFocusManager;
import jp.ize.ux.states.UXBasicState;
import jp.ize.ux.components.UXComponentResource;
import jp.ize.ux.components.UXComponent;
import jp.ize.ux.components.UXItem;
import jp.ize.ux.interactions.UXGeneralInteraction;
import jp.ize.ux.utils.UXRange;
import jp.ize.ux.events.UXMouseEvent;
import jp.ize.ux.acts.Act;
import jp.ize.ux.acts.SelectAct;

#if flash9
import flash.text.TextField;
#elseif flash
import flash.TextField;
#end
// }}}
// {{{ enum UXSelectionPolicy
enum UXSelectionPolicy {
	EXCLUSIVE;
	MULTI;
}
// }}}
// {{{ class UXSelectorState extends UXListState
/**
 * UXSelectorState クラス<br>
 * UXSelectorの現在の状態を表すオブジェクトです。
 */
class UXSelectorState extends UXListState
{
	// {{{ public var policy : UXSelectionPolicy;
	/**
	* どのような選択方法にするかのポリシーです。
	*/
	public var policy : UXSelectionPolicy;
	// }}}
	// {{{ public var items : Array<UXItem>;
	/**
	* 選択アイテム一覧です。
	*/
	public var items : Array<UXItem>;
	// }}}
	// {{{ public var selections( default, default ) : Array<UXItem>;
	/**
	 * 現在選択されているラジオボタンのインスタンスを返します。
	 */
	public var selections( default, default ) : Array<UXItem>;
	// }}}
	// {{{ public var background( default, default ) : UXComponentResource
	/**
	 * チェックをする矩形部分のコンポーネントです。
	 */
	public var background( default, default ) : UXComponentResource;
	// }}}
	// {{{ public var acts(default, null) : SelectAct
	/**
	 * デフォルトの動きです。
	 */
	public var acts(default, null) : SelectAct;
	// }}}
	// {{{ public function new( policy:UXSelectionPolicy, ?bg:UXComponentResource ) : Void
	/**
	 * コンストラクタです。
	 *
	 * @param policy: EXCLUSIVE（排他的選択）か MULTI（複数同時選択）かを指定します。
	 * @param bg: 背景リソースを指定します。
	 */
	public function new( policy:UXSelectionPolicy, ?bg:UXComponentResource ) : Void
	{
		super();
		items = new Array();
		selections = new Array();
		background = bg;
		var ex:Bool = false;
		switch ( policy ) {
			case EXCLUSIVE:
				ex = true;
			case MULTI:
				ex = false;
		}
		var sa = function(c) {
			var item = cast(c,UXItem);
			Act.exec(item.state.acts.select(),item.state);
		}
		var da = function(c) {
			var item = cast(c,UXItem);
			var f = 
			Act.exec(item.state.acts.deselect(),item.state);
		}
		acts = new SelectAct(ex,sa,da);
	}
	// }}}
	// {{{ private function attachResource() : Void
	/**
	 * グローバルなリソースをresourceプロパティに取得する関数です。
	 */
	private function attachResource() : Void
	{
	}
	// }}}
}
// }}}

// {{{ class UXSelector extends UXComponent<UXSelectorState>
/**
 * UXSelectorクラス<br>
 * 複数の選択肢から一つだけユーザーに選択させるコンポーネントです。
 * このコンポーネントを使用する場合は、少なくとも二つ以上のSelectorインスタンスと、
 * それらが含まれるグループを構成して使用します。一つのグループ内では常に一つ以下だけしか選択できません。<br>
 *
 * @author		iZE Co., Ltd.<br>
 * @version		$Id$<br>
 */
class UXSelector extends UXComponent<UXSelectorState>
{
	// {{{ properties
	// }}}
	// {{{ public function new( policy:UXSelectionPolicy, ?items:Array<UXItem>, ?background:UXComponentResource )
	/**
	 * コンストラクタです。
	 *
	 * @param policy: EXCLUSIVE（排他的選択）か MULTI（複数同時選択）かを指定します。
	 * @param items: 選択肢用の初期オブジェクトを配列で指定します。省略可能です。
	 * @param background: 背景リソースの指定です。
	 */
	public function new( policy:UXSelectionPolicy, ?items:Array<UXItem>, ?background:UXComponentResource )
	{
		if ( items==null ) items = new Array();
		state = new UXSelectorState(policy,background);
		state.items  = items;
		state.target = this;
		ctrl = new UXController<UXSelectorState>( state );
		ctrl.addInteraction( new UXSelectorSelectInteraction() );
		super(ctrl);
		if ( background!=null ) {
			addChild(background);
		}
		ctrl.getInteraction("Select").addReactEvent( UXMouseEvent.CLICK );
		var actf = function(st:ListStateType):Int {
			var index:Int = -1;
			var s = cast(st,UXSelectorState);
			for ( i in 0...s.items.length ) {
				if ( s.items[i].hitTest(s.eventTarget) ) {
					index = i;
				}
			}
			return index;
		}
		ctrl.getInteraction("Select").addAct(state.acts.select(actf));
	}
	// }}}
	// {{{ public function refreshResource() : Void
	/**
	 * グローバルなリソースを再取得する関数です。
	 */
	public function refreshResource() : Void
	{
	}
	// }}}
	// {{{ public function update( updator : UXSelectorState -> Void ) : Void
	/**
	 * このコンポーネントの状態を直接変更するメソッドです。状態のどんな操作も可能になるので、
	 * このメソッドの使用には注意が必要です。
	 */
	public function update( updator : UXSelectorState -> Void ) : Void
	{
		updator( state );
	}
	// }}}
	// {{{ public function addUXChild( c : UXObject ) : Void
	/**
	 * addChild オーバーライドメソッドです。引数として受け取った子オブジェクトを追加し、
	 * このコンポーネントの状態やコントーラーに反映させます。
	 */
	public override function addUXChild( c : UXObject ) : Void
	{
		super.addUXChild( c );
		state.children.push( c );
		state.items.push( cast(c) );
	}
	// }}}
	// {{{ public function removeUXChild( c : UXObject ) : Void
	/**
	 * removeChild オーバーライドメソッドです。引数として受け取った子オブジェクトを削除し、
	 * このコンポーネントの状態やコントローラーに反映させます。
	 */
	public override function removeUXChild( c : UXObject ) : Void
	{
		super.removeUXChild(c);
		state.children.remove( c );
		state.items.remove( cast(c) );
	}
	// }}}
	// {{{ public function getSelectionValues() : Array<Dynamic>
	/**
	* 選択状態にあるすべての子コンポーネントを配列として返します。
	*/
	public function getSelectionValues() : Array<Dynamic>
	{
		var ret:Array<Dynamic> = new Array();
		for ( item in state.items ) {
			if ( item.selected ) {
				ret.push( item.getValue() );
			}
		}
		return ret;
	}

	// }}}
	// {{{ public function select( c:UXItem ) : Void
	/**
	* 指定された子コンポーネントを選択状態にします。
	*/
	public function select( c:UXItem ) : Void
	{
		c.selected = true;
		Act.exec(c.state.acts.select(), c.state);
	}

	// }}}
	// {{{ public function deselect( c:UXItem ) : Void
	/**
	* 指定された子コンポーネントを非選択状態にします。
	*/
	public function deselect( c:UXItem ) : Void
	{
		c.selected = false;
		Act.exec(c.state.acts.deselect(), c.state);
	}

	// }}}
}
// }}}

// {{{ class UXSelectorSelectInteraction extends UXGeneralInteraction<UXSelectorState>
/**
 * UXSelectorSelectInteraction クラス<br>
 * ラジオボタンがチェックされた、またはチェック解除されたことに対するデフォルトインタラクションです。
 */
class UXSelectorSelectInteraction extends UXGeneralInteraction<UXSelectorState>
{
	// {{{ public function new() : Void
	/**
	* コンストラクタ
	*/
	public function new() : Void
	{
		super("Select");
	}

	// }}}
}
// }}}
